const std = @import("std");

pub fn ResStat(T0: type, T1: type, deiniter: fn (T0, T1) void) type {
    const SingList = std.SinglyLinkedList(T0);
    const Node = SingList.Node;
    return struct {
        const Self: type = @This();

        allocator: std.mem.Allocator,
        resource_list: SingList,
        is_err: bool,
        comptime resource_deiniter: @TypeOf(deiniter) = deiniter,

        pub fn init(_allocator: std.mem.Allocator) !Self {
            return Self{
                .allocator = _allocator,
                .resource_list = .{ .first = null },
                .is_err = false,
            };
        }
        pub fn reinit(p_self: *Self, resource: T0) !void {
            const p_node = try p_self.allocator.create(Node); // <+><+>
            errdefer p_self.allocator.destroy(p_node);
            p_node.* = Node{ .data = resource };
            p_self.resource_list.prepend(p_node);
        }
        pub const IsErr: type = union(enum) { normal, err: T1 };
        pub fn deinit(
            p_self: *Self,
            is_err: IsErr,
        ) void {
            while (p_self.resource_list.popFirst()) |p_node| {
                switch (is_err) {
                    .err => |deiniter_args| p_self.resource_deiniter(p_node.data, deiniter_args),
                    .normal => {},
                }
                p_self.allocator.destroy(p_node);
            }
        }
    };
}
